package main

import (
	"fmt"
	"math/rand"
	"sort"
	"time"
)

func topic1() {
	s1 := make([]int, 3, 4)
	s2 := append(s1, 1)
	// 分别打印s1，s2
	fmt.Printf("s1为%v，内存地址为%p\n", s1, &s1)
	fmt.Printf("s2为%v，内存地址为%p\n", s2, &s2)
	// 修改s1，发现s2也变化了
	s1[0] = 6
	fmt.Println("将s1的第1个元素改为6之后:")
	fmt.Printf("s1为%v，内存地址为%p\n", s1, &s1)
	fmt.Printf("s2为%v，内存地址为%p\n", s2, &s2)
	// 修改s2的前3个元素，发现s1也变化了
	s2[2] = 9
	fmt.Println("将s2的第3个元素改为9之后:")
	fmt.Printf("s1为%v，内存地址为%p\n", s1, &s1)
	fmt.Printf("s2为%v，内存地址为%p\n", s2, &s2)
	// 给s2添加一个元素，s2的长度增加一倍
	s2 = append(s2, 3)
	fmt.Println("给s2添加一个元素后：")
	fmt.Printf("s1为%v，内存地址为%p，长度为%d，容量为%d\n", s1, &s1, len(s1), cap(s1))
	fmt.Printf("s2为%v，内存地址为%p,长度为%d，容量为%d\n", s2, &s2, len(s2), cap(s2))
}

func topic2() {
	// 定义一个数组a
	var a = [...]int{1, 4, 9, 16, 2, 5, 10, 15}
	// 初始化切片slice
	slice := []int{}
	// 定义两个变量c,i
	// 变量i当做数组a的索引，c=i+1，a[c]取a[i]后面的数值
	// a[i]+a[c]是相邻两个值的和，将和追加到切片slice
	// 当i=len(a)-1时，c=len(a),所有值全部取完，和计算完
	fmt.Println("相邻两个数取值:")
	for c, i := 0, 0; i < len(a)-1; i++ {
		c = i + 1
		fmt.Printf("%d,%d\n", a[i], a[c])
		slice = append(slice, a[i]+a[c])
	}
	fmt.Printf("新切片为：\n%v\n", slice)
}

// map以key降序排序
func Map(m map[int]int) (result map[int]int, keys []int) {
	result = m
	keys = []int{}
	for key := range result {
		keys = append(keys, key)
	}
	sort.Sort(sort.Reverse(sort.IntSlice(keys)))
	return
}

// 利用map输出切片元素重复值
func topic3() {
	// 定义随机数
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	// 生成随机数切片
	slice := []int{}
	for i := 0; i < 100; i++ {
		num := r.Intn(201) - 100
		slice = append(slice, int(num))
	}
	fmt.Println("原切片：\n", slice)
	sort.Slice(slice, func(i, j int) bool {
		return slice[i] > slice[j]
	})
	fmt.Println("原切片降序排序：\n", slice)
	// 将切片遍历，生成map,key为切片元素，value为重复出现的次数
	m1 := make(map[int]int)
	for _, item := range slice {
		_, exist := m1[item]
		if exist {
			m1[item] += 1
		} else {
			m1[item] = 1
		}
	}
	// 将切片打印为map
	// fmt.Println("原map为：", m1)
	mapResult, keys := Map(m1)
	for _, key := range keys {
		fmt.Printf("随机数 %v ,重复了 %v 次\n", key, mapResult[key])
	}
}

func main() {
	fmt.Println("~~~~~~这是第1题答案~~~~~~")
	topic1()
	fmt.Println("~~~~~~这是第2题答案~~~~~~")
	topic2()
	fmt.Println("~~~~~~这是第3题答案~~~~~~")
	topic3()
}


// 批改意见
// 1. 最后一题，随机数范围是[-100, 100]，Intn(200)的范围是[0, 200)，会漏掉100这个值
// 马某人：那就把200改成201吧